package vaccine.appointment.system.schedule;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import vaccine.appointment.system.appointmentrecord.dataobject.AppointmentRecord;
import vaccine.appointment.system.appointmentrecord.enums.AppointmentStatusEnum;
import vaccine.appointment.system.appointmentrecord.mapper.AppointmentRecordMapper;
import vaccine.appointment.system.common.enums.DelFlgEnum;
import vaccine.appointment.system.inventory.dataobject.Inventory;
import vaccine.appointment.system.inventory.mapper.InventoryMapper;
import vaccine.appointment.system.person.dataobject.Person;
import vaccine.appointment.system.person.mapper.PersonMapper;
import vaccine.appointment.system.vaccine.dataobject.Vaccine;
import vaccine.appointment.system.vaccine.mapper.VaccineMapper;
import vaccine.appointment.system.vaccinationsite.dataobject.VaccinationSite;
import vaccine.appointment.system.vaccinationsite.mapper.VaccinationSiteMapper;

import java.time.LocalDate;
import java.util.List;

/**
 * 定时任务
 */
@Slf4j
@Component
public class ScheduledTasks {

    @Autowired
    private VaccineMapper vaccineMapper;

    @Autowired
    private AppointmentRecordMapper appointmentRecordMapper;

    @Autowired
    private InventoryMapper inventoryMapper;

    @Autowired
    private PersonMapper personMapper;

    @Autowired
    private VaccinationSiteMapper vaccinationSiteMapper;

    /**
     * 疫苗过期处理
     * 每天凌晨1点执行
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void handleExpiredVaccines() {
        log.info("开始执行疫苗过期处理任务");
        
        try {
            // 查询所有过期的疫苗
            QueryWrapper<Vaccine> queryWrapper = new QueryWrapper<>();
            queryWrapper.lt("validity_period", LocalDate.now());
            queryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
            List<Vaccine> expiredVaccines = vaccineMapper.selectList(queryWrapper);

            if (expiredVaccines.isEmpty()) {
                log.info("没有过期的疫苗");
                return;
            }

            int count = 0;
            for (Vaccine vaccine : expiredVaccines) {
                // 记录过期疫苗信息
                log.warn("疫苗已过期: ID={}, 名称={}, 过期日期={}", 
                    vaccine.getId(), vaccine.getName(), vaccine.getValidityPeriod());
                
                // 可以在这里添加其他处理逻辑，比如：
                // 1. 发送通知给管理员
                // 2. 自动清理过期疫苗的库存
                // 3. 记录到日志表
                
                count++;
            }

            log.info("疫苗过期处理任务完成，共处理 {} 个过期疫苗", count);
        } catch (Exception e) {
            log.error("疫苗过期处理任务执行失败", e);
        }
    }

    /**
     * 逾期预约通知
     * 每天早上8点执行
     */
    @Scheduled(cron = "0 0 8 * * ?")
    public void notifyOverdueAppointments() {
        log.info("开始执行逾期预约通知任务");
        
        try {
            // 查询所有逾期未接种的预约（预约时间在今天之前，状态为已预约）
            QueryWrapper<AppointmentRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.lt("appointment_time", LocalDate.now());
            queryWrapper.eq("appointment_status", AppointmentStatusEnum.APPOINTED.getCode());
            queryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
            List<AppointmentRecord> overdueAppointments = appointmentRecordMapper.selectList(queryWrapper);

            if (overdueAppointments.isEmpty()) {
                log.info("没有逾期的预约");
                return;
            }

            int count = 0;
            for (AppointmentRecord record : overdueAppointments) {
                // 获取接种人信息
                Person person = personMapper.selectById(record.getPersonId());
                
                // 获取疫苗信息
                Vaccine vaccine = vaccineMapper.selectById(record.getVaccineId());
                
                // 获取接种点信息
                VaccinationSite site = vaccinationSiteMapper.selectById(record.getVaccinationSiteId());

                if (person != null && vaccine != null && site != null) {
                    log.warn("逾期预约提醒: 预约ID={}, 接种人={}, 疫苗={}, 接种点={}, 预约时间={}", 
                        record.getId(), person.getName(), vaccine.getName(), 
                        site.getName(), record.getAppointmentTime());
                    
                    // 可以在这里添加通知逻辑，比如：
                    // 1. 发送短信通知
                    // 2. 发送邮件通知
                    // 3. 推送APP通知
                    
                    count++;
                }
            }

            log.info("逾期预约通知任务完成，共处理 {} 个逾期预约", count);
        } catch (Exception e) {
            log.error("逾期预约通知任务执行失败", e);
        }
    }

    /**
     * 低库存预警
     * 每天早上9点和下午3点执行
     */
    @Scheduled(cron = "0 0 9,15 * * ?")
    public void checkLowStockAlert() {
        log.info("开始执行低库存预警任务");
        
        try {
            // 查询所有库存
            QueryWrapper<Inventory> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
            List<Inventory> inventoryList = inventoryMapper.selectList(queryWrapper);

            if (inventoryList.isEmpty()) {
                log.info("没有库存记录");
                return;
            }

            int lowStockCount = 0;
            int criticalStockCount = 0;
            int threshold = 10; // 低库存阈值

            for (Inventory inventory : inventoryList) {
                if (inventory.getCount() < threshold) {
                    // 只有当vaccineId不为null时才查询疫苗信息
                    if (inventory.getVaccineId() == null) {
                        continue; // 跳过vaccineId为null的库存记录
                    }
                    
                    // 获取疫苗信息
                    Vaccine vaccine = vaccineMapper.selectById(inventory.getVaccineId());
                    
                    // 获取接种点信息
                    VaccinationSite site = vaccinationSiteMapper.selectById(inventory.getVaccinationSiteId());

                    if (vaccine != null && site != null) {
                        if (inventory.getCount() < threshold / 2) {
                            // 严重低库存
                            log.error("严重低库存预警: 疫苗={}, 接种点={}, 当前库存={}", 
                                vaccine.getName(), site.getName(), inventory.getCount());
                            criticalStockCount++;
                        } else {
                            // 低库存
                            log.warn("低库存预警: 疫苗={}, 接种点={}, 当前库存={}", 
                                vaccine.getName(), site.getName(), inventory.getCount());
                            lowStockCount++;
                        }
                        
                        // 可以在这里添加预警通知逻辑，比如：
                        // 1. 发送邮件给管理员
                        // 2. 推送系统通知
                        // 3. 记录到预警日志表
                    }
                }
            }

            log.info("低库存预警任务完成，低库存: {} 个，严重低库存: {} 个", 
                lowStockCount, criticalStockCount);
        } catch (Exception e) {
            log.error("低库存预警任务执行失败", e);
        }
    }

    /**
     * 自动取消逾期预约
     * 每天凌晨2点执行
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void autoCancelOverdueAppointments() {
        log.info("开始执行自动取消逾期预约任务");
        
        try {
            // 查询所有逾期7天以上未接种的预约
            LocalDate sevenDaysAgo = LocalDate.now().minusDays(7);
            QueryWrapper<AppointmentRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.lt("appointment_time", sevenDaysAgo);
            queryWrapper.eq("appointment_status", AppointmentStatusEnum.APPOINTED.getCode());
            queryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
            List<AppointmentRecord> overdueAppointments = appointmentRecordMapper.selectList(queryWrapper);

            if (overdueAppointments.isEmpty()) {
                log.info("没有需要自动取消的逾期预约");
                return;
            }

            int count = 0;
            for (AppointmentRecord record : overdueAppointments) {
                // 更新状态为已取消
                record.setAppointmentStatus(AppointmentStatusEnum.CANCELLED.getCode());
                appointmentRecordMapper.updateById(record);

                // 恢复库存
                QueryWrapper<Inventory> inventoryQueryWrapper = new QueryWrapper<>();
                inventoryQueryWrapper.eq("vaccine_id", record.getVaccineId());
                inventoryQueryWrapper.eq("vaccination_site_id", record.getVaccinationSiteId());
                inventoryQueryWrapper.eq("del_flg", DelFlgEnum.NOT_DELETED.getCode());
                Inventory inventory = inventoryMapper.selectOne(inventoryQueryWrapper);

                if (inventory != null) {
                    inventoryMapper.increaseStock(inventory.getId(), 1);
                }

                log.info("自动取消逾期预约: ID={}, 预约时间={}", record.getId(), record.getAppointmentTime());
                count++;
            }

            log.info("自动取消逾期预约任务完成，共取消 {} 个预约", count);
        } catch (Exception e) {
            log.error("自动取消逾期预约任务执行失败", e);
        }
    }
}

